﻿'Copyright (c) 2012, Onur KESKİN
'All rights reserved.

'Redistribution and use in source and binary forms, with or without modification, are permitted provided that 
'the following conditions are met:

'Redistributions of source code must retain the above copyright notice, this list of conditions and the following 
'disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 
'the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the 
'name of the Dokuz Eylul University, Izmir nor the names of its contributors may be used to endorse or promote products derived 
'from this software without specific prior written permission. 

'THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
'INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
'ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
'INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
'SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
'ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
'ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Imports System.IO
Imports System.IO.Ports

Public Class Main

    Dim message, model, cmd As String
    Dim afrt, amax, amin, ares, dmin, dmax, scan, cluster As Integer
    Dim list_data As New List(Of Integer)
    Dim fileName As String = "urg_veri"
    ' Lazer bilgilerini alma fonksiyon
    Public Sub getInfo()
        If (message.StartsWith("PP")) Then
            lblModel.Text = "MODEL"
            lblDmin.Text = "DMIN"
            lblDmax.Text = "DMAX"
            lblAres.Text = "ARES"
            lblAmin.Text = "AMIN"
            lblAmax.Text = "AMAX"
            lblAfrt.Text = "AFRT"
            lblScan.Text = "SCAN"
            txtDebug.Clear()
            message = message.Replace("PP", "").Replace("00P", "").Trim()
            Dim t_param() As String = message.Split(";")
            Dim temp As String = ""
            For Each par As String In t_param
                If par.Length > 1 Then
                    temp += par.Remove(0, 2).Trim().Split(":")(1) & ";"
                End If
            Next
            temp = temp.Substring(0, temp.Length - 1)
            t_param = temp.Split(";")
            model = t_param(0)
            dmin = t_param(1)
            dmax = t_param(2)
            ares = t_param(3)
            amin = t_param(4)
            amax = t_param(5)
            afrt = t_param(6)
            scan = t_param(7)
            cluster = 1
            lblModel.Text += ": " & model
            lblDmin.Text += ": " & dmin
            lblDmax.Text += ": " & dmax
            lblAres.Text += ": " & ares
            lblAmin.Text += ": " & amin
            lblAmax.Text += ": " & amax
            lblAfrt.Text += ": " & afrt
            lblScan.Text += ": " & scan
            txtAmax.Text = amax
            txtAmin.Text = amin
            txtCluster.Text = cluster
            If amax > 0 And amin > 0 And cluster >= 0 Then
                GroupBox1.Enabled = True
            End If
        End If
    End Sub
    ' Ölçüm bilgilerini alma fonksiyonu
    Public Sub getData()
        If (message.StartsWith("GD")) Then
            Dim temp() As String = message.Split(vbLf)
            Dim line As String = ""
            Dim mean As Double
            list_data.Clear()
            For i As Integer = 0 To temp.Length - 1
                If (i > 2 And temp(i).Length > 0) Then
                    line = line & temp(i).Substring(0, temp(i).Length - 1).ToString()
                End If
            Next

            line = line.Substring(0, line.Length - 1)
            For i As Integer = 0 To amin - 1
                list_data.Insert(i, -1)
            Next

            list_data.AddRange(decode_str(line, 3))

            For i As Integer = 0 To list_data.Count - 1
                If list_data(i) > -1 And (list_data(i) > dmax Or list_data(i) < dmin) Then
                    list_data(i) = 6000
                End If
            Next
            mean = (list_data(afrt - 1) + list_data(afrt) + list_data(afrt + 1)) / 3
            GroupBox4.Enabled = True
            txtFront.Text = Int(mean)
            lbData.DataSource = list_data
        End If
    End Sub
    Public Function between(num As Integer, min As Integer, max As Integer) As Boolean
        If num <= max And num >= min Then
            Return True
        Else
            Return False
        End If
    End Function
    '6-Bitlik kodu çözme fonksiyonu
    Public Function decode(enc As String) As Integer
        Dim dec As Integer = 0
        For Each c As Char In enc
            dec <<= 6
            dec = dec And (Not 63)
            dec = dec Or (Asc(c) - 48)
        Next
        Return dec
    End Function
    'Kodlanmış sensor verisini çözme fonksiyonu
    Public Function decode_str(enc As String, coding As Byte) As List(Of Integer)
        Dim temp As String = ""
        Dim dec As New List(Of Integer)
        For i As Integer = 0 To enc.Length Step coding
            If i < enc.Length - coding Then
                temp = enc.Substring(i, coding)
            Else
                temp = enc.Substring(i)
            End If
            dec.Add(decode(temp))
        Next
        Return dec
    End Function

    Public Sub startup(status As Boolean)
        btnDisconnect.Enabled = status
        btnRead.Enabled = status
        btnStart.Enabled = status
        btnStop.Enabled = status
        btnConnect.Enabled = status
        btnDisconnect.Enabled = status
        btnConnect.Enabled = Not status
        btnRead.Enabled = status

        txtCommand.Enabled = status
        txtDebug.Enabled = status
        txtAmax.Enabled = status
        txtAmin.Enabled = status
        txtCluster.Enabled = status

        SerialConnectionInfoToolStripMenuItem.Enabled = status
    End Sub

    Private Sub btnConnect_Click(sender As System.Object, e As System.EventArgs) Handles btnConnect.Click
        URGport.PortName = cbPortNames.Text
        If (URGport.IsOpen = False) Then
            Try
                URGport.Open()
                URGport.Write("SCIP2.0" & vbLf & "RS" & vbLf & "BM" & vbLf)

                Dim ye As String = URGport.ReadExisting().Trim().Replace(vbLf, ";").Replace(";;", ";")

                While (ye.EndsWith("00P"))
                    URGport.Write("BM" & vbLf)
                    ye = URGport.ReadExisting().Trim().Replace(vbLf, ";").Replace(";;", ";")
                End While

                lblStatus.Text = "Lazer AÇIK"
                startup(True)
            Catch ex As Exception
                MessageBox.Show("Seri port bilgisini kontrol ediniz", "Uyarı", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
        End If
    End Sub

    Private Sub btnDisconnect_Click(sender As System.Object, e As System.EventArgs) Handles btnDisconnect.Click
        If (URGport.IsOpen = True) Then
            URGport.Write("QT" & vbCrLf)
            lblStatus.Text = "Lazer KAPALI"
            URGport.Close()
            URGtimer.Enabled = False
            txtDebug.Clear()
            startup(False)
            MessageBox.Show(URGport.PortName & " portu kapatıldı.", "Bilgi", MessageBoxButtons.OK, MessageBoxIcon.Information)
        End If
    End Sub

    Private Sub btnRead_Click(sender As System.Object, e As System.EventArgs) Handles btnRead.Click
        If (txtCommand.Text.Length > 0) Then
            URGport.Write(txtCommand.Text & vbCrLf)
        End If
    End Sub

    Private Sub Main_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        startup(False)
        GroupBox1.Enabled = False
        GroupBox4.Enabled = False
        MeasuredDataToolStripMenuItem.Enabled = False
        Dim portName As String

        For i As Integer = 0 To My.Computer.Ports.SerialPortNames.Count - 1
            portName = My.Computer.Ports.SerialPortNames(i)
            If (IsNumeric(portName.Remove(0, portName.Length - 1)) = False) Then
                portName = portName.Substring(0, portName.Length - 1)
            End If
            cbPortNames.Items.Add(portName)
        Next
        cbPortNames.SelectedIndex = cbPortNames.Items.Count - 1
    End Sub

    Private Sub URGport_DataReceived(sender As System.Object, e As System.IO.Ports.SerialDataReceivedEventArgs) Handles URGport.DataReceived
        Me.Invoke(New EventHandler(AddressOf DoUpdate))
    End Sub

    Private Sub DoUpdate(s As Object, e As EventArgs)
        message = URGport.ReadExisting()
        getInfo()
        getData()
        txtDebug.Text = message.Replace(vbLf, vbCrLf)
    End Sub

    Private Sub btnStart_Click(sender As System.Object, e As System.EventArgs) Handles btnStart.Click
        If (between(Convert.ToInt32(txtAmin.Text), amin, amax) And _
            between(Convert.ToInt32(txtAmax.Text), amin, amax) And _
            between(Convert.ToInt32(txtCluster.Text), 1, 99)) Then
            cmd = "GD" & txtAmin.Text.PadLeft(4, "0") & txtAmax.Text.PadLeft(4, "0") & txtCluster.Text.PadLeft(2, "0")
            URGtimer.Enabled = True
        Else
            URGtimer.Enabled = False
            MessageBox.Show("Parametre hatası !")
        End If
    End Sub

    Private Sub btnStop_Click(sender As System.Object, e As System.EventArgs) Handles btnStop.Click
        URGtimer.Enabled = False
        Dim f As Integer = 0
        While (File.Exists(fileName & ".csv") = True)
            f += 1
            fileName = "urg_veri" & "_" & f
        End While
        Using writer As StreamWriter = New StreamWriter(fileName & ".csv")
            writer.WriteLine("nokta;veri")
            Dim i As Integer = 0

            For Each a As Integer In list_data
                writer.WriteLine(i & ";" & a)
                i += 1
            Next
        End Using
        MeasuredDataToolStripMenuItem.Enabled = True
        MessageBox.Show("Veriler başarı ile " & fileName & ".csv dosyasına kaydedildi.", "Bilgi", MessageBoxButtons.OK, MessageBoxIcon.Information)
    End Sub

    Private Sub URGTimer_Tick(sender As System.Object, e As System.EventArgs) Handles URGtimer.Tick
        URGport.Write(cmd & vbCrLf)
    End Sub

    Private Sub SpecialCommandsToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles SpecialCommandsToolStripMenuItem.Click
        Dim sForm As New Help()
        sForm.Show()
    End Sub

    Private Sub AboutToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles AboutToolStripMenuItem.Click
        Dim aForm As New About()
        aForm.Show()
    End Sub

    Private Sub ExitToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles ExitToolStripMenuItem.Click
        Me.Close()
    End Sub

    Private Sub MeasuredDataToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles MeasuredDataToolStripMenuItem.Click
        Process.Start("explorer.exe", Application.StartupPath())
    End Sub

    Private Sub SerialConnectionInfoToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles SerialConnectionInfoToolStripMenuItem.Click
        Dim info As String = "Port: " & URGport.PortName & vbCrLf & _
                             "Baudrate: " & URGport.BaudRate & vbCrLf & _
                             "Handshake: XOnXoff" & vbCrLf & _
                             "Parity: None" & vbCrLf & _
                             "Data bits: " & URGport.DataBits & vbCrLf & _
                             "Stop bit: One" & vbCrLf
        MessageBox.Show(info, "Seri Bağlantı Bilgisi", MessageBoxButtons.OK, MessageBoxIcon.None)
    End Sub
End Class
